from rest_framework import serializers
from orders.models import OrdersModel,OrdersDetailModel
from django_redis import get_redis_connection
from coupon.models import CouponLogModel
from django.db import transaction
import datetime
from AskDoctor.models import DoctorModel
from dingxiang.utils import constants
import traceback

class OrderModelSerializer(serializers.ModelSerializer):
    user_coupon_id = serializers.IntegerField(write_only=True,default=None)
    class Meta():
        model = OrdersModel
        fields = ['id','pay_type','credit','user_coupon_id']
        extra_kwargs = {
            "pay_type":{"write_only":True},
            "credit":{"write_only":True}
        }

    def create(self, validated_data):

        user = self.context['request'].user
        user_id = user.id

        redis = get_redis_connection('cart')

        cart_hash = redis.hgetall(f"cart_{user_id}")

        if len(cart_hash)<1:
            raise serializers.ValidationError(detail="购物车中没有商品",code="cart_empty")

        user_credit = int(validated_data.get('credit',0))

        if user_credit > 0 and user_credit > user.credit:
            raise serializers.ValidationError(detail="您本次积分不够划扣",code="credit_error")

        user_coupon_id = validated_data.get('user_coupon_id',None)
        user_coupon1 = None
        if user_coupon_id is not None:
            user_coupon1 = CouponLogModel.objects.filter(id=user_coupon_id,user_id=user_id).first()

        with transaction.atomic():
            t1 = transaction.savepoint()

            try:
                orders = OrdersModel.objects.create(
                    name="浮光商城购买下单",
                    user_id=user_id,
                    order_number= datetime.datetime.now().strftime("%Y%m%d")+str(("%08d" % user_id)) + "%08d" % redis.incr('order_number'),
                    pay_type=validated_data.get('pay_type')
                )

                course_id_list = [int(key.decode()) for key,value in cart_hash.items() if value==b'1']

                course_list = DoctorModel.objects.filter(id__in=course_id_list,is_deleted=False,is_show=True)

                total_price = 0
                real_price = 0

                total_discount_price = 0

                max_discount_coutse = None

                max_use_credit = 0


                detail_list = []
                for course in course_list:

                    discount_price = course.discount.get('price',course.price)
                    discount_name = course.discount.get('type',"")

                    total_price += course.price

                    real_price += discount_price

                    detail_list.append(OrdersDetailModel(
                        order=orders,
                        course=course,
                        price=course.price,
                        real_price=discount_price,
                        discount_name=discount_name
                    ))

                    if user_coupon_id:
                        if max_discount_coutse is None:
                            max_discount_coutse = course
                        else:

                            if course.price >= max_discount_coutse.price:
                                max_discount_coutse = course

                    if user_credit >0 and course.credit>0:
                        max_use_credit += course.credit

                OrdersDetailModel.objects.bulk_create(detail_list)

                if user_coupon1:
                    sale = user_coupon1.coupon.sale[1:]

                    if user_coupon1.coupon.discount==1:
                        total_discount_price = float(sale)

                    elif user_coupon1.coupon.discount==2:
                        total_discount_price = max_discount_coutse.price * (1-float(sale))

                if user_credit >0 :
                    if max_use_credit < user_credit:
                        raise serializers.ValidationError(detail="超过当前最大可用积分限制",code="credit_max")

                    orders.credit = user_credit
                    total_discount_price = float(user_credit/constants.CREDIT_TO_MONEY)
                    user.credit = user.credit - user_credit
                    user.save()

                orders.total_price = total_price
                orders.real_price = float(real_price) - total_discount_price
                orders.save()

                cart = {key:value for key,value in cart_hash.items() if value == b'0'}

                pipe = redis.pipeline()
                pipe.multi()
                pipe.delete(f"cart_{user_id}")
                if len(cart)>0:
                    pipe.hset(f"cart_{user_id}",mapping=cart)
                pipe.execute()

                if user_coupon1:

                    user_coupon1.order = orders
                    user_coupon1.save()
                    redis = get_redis_connection('coupon')
                    redis.delete(f"{user_id}:{user_coupon_id}")

                return orders

            except Exception as es:
                print('当前订单生成失败....')
                print(es)

                print(f"An error occurred: {type(es).__name__} - {es}")

                traceback.print_exc()

                transaction.savepoint_rollback(t1)
                raise serializers.ValidationError(detail="订单生成失败，请稍后再试...",code="order_error")


class OrderDetailModelSerializer(serializers.ModelSerializer):
    course_id = serializers.IntegerField(source="course.id")
    course_name = serializers.CharField(source='course.name')
    course_cover = serializers.ImageField(source='course.course_cover')
    class Meta():
        model = OrdersDetailModel
        fields = ['id','price','real_price','discount_name','course_id','course_name','course_cover']


class OrderListModelSerializer(serializers.ModelSerializer):
    order_detail = OrderDetailModelSerializer(many=True)
    class Meta():
        model = OrdersModel
        fields = ['id','total_price','real_price','order_number','order_status','pay_type','order_desc','pay_time','credit','coupon','order_detail','created_time']